#include "qtcpthread.h"

//add by dimon, 2024-03-18 15:125
#include "common.h"
#include "quser.h"
#include <QtNetwork>
#include <QTcpSocket>
#include <QtDebug>

//父基类为 QThread
QTcpThread::QTcpThread(int socketDescriptor, QObject *parent) :
    QThread(parent), socketDescriptor(socketDescriptor)
{

}

QTcpThread::~QTcpThread(){

}

//add by dimon, 2024-03-18 15:125

///处理来自客户端的注册或的登陆请求
void QTcpThread::onReadyRead()
{


    qDebug() <<"[" << __FILE__ << "]" << " " << __FUNCTION__ << ":" << __LINE__;
    qDebug() << "Current thread is: " << QThread::currentThread();

    db = new QMyDB;

    //从tcpSocket读取数据到'QByteArray'中
    QByteArray block = tcpSocket->readAll();
    //从'QByteArry'字节数组创建 'QDataStream' 数据流
    QDataStream in(&block, QIODevice::ReadOnly);
    quint16 dataSize;
    quint8 msgType;
    in >> dataSize  >> msgType;


    qDebug() << "Current thread is: " << QThread::currentThread();
    qDebug() << "QTcpThread's QTcpSocket's SLOTS(onReadyRead()) " << "msgType " << msgType;
    switch(msgType){
    case MSG_CLIENT_REG: //注册
    {
        QString name;
        QString password;
        in >> name >> password;

        //响应
        QByteArray block;
        QDataStream out(&block, QIODevice::WriteOnly);
        out.setVersion(QDataStream::Qt_5_4);

        qDebug() << "QTcpThread's DB->newUser()" << "to create new User";
        quint32 userid = db->newUser(password,name);
        quint8 msgType;
        if(userid == 0)
            msgType = MSG_SERVER_REG_FAILED;
        else
            msgType = MSG_SERVER_REG_SUCCESS;
        out << (quint16)0 << msgType << userid;
        out.device()->seek(0);
        out << (qint16)(block.size() - sizeof(quint16));

        qDebug() << "Current thread is: " << QThread::currentThread();
        qDebug() << "tcpSocket wirte QByteArray to socket";
        tcpSocket->write(block);

        qDebug() << "Add new User success";
        break;
    }
    case MSG_CLIENT_LOGIN:
    {
        quint32 id;
        QString password;
        in >> id >> password;

        //响应
        QByteArray block;
        QDataStream out(&block, QIODevice::WriteOnly);
        out.setVersion(QDataStream::Qt_5_4);

        QUser user;
        quint8 msgType;

        qDebug() << __FILE__<< __FUNCTION__ << "(): " << "getUserInfo:id=" << id;
        if(!db->getUserInfo(id,&user))
            msgType = MSG_SERVER_LOGIN_ERR_ID; //账号不存在
        else{
            qDebug() << __FILE__<< __FUNCTION__ << "(): " << __LINE__ <<"user.password" << user.password;
            qDebug() << __FILE__<< __FUNCTION__ << "(): " << __LINE__ <<"user.name" << user.name;
            if(user.password != password)
                msgType = MSG_SERVER_LOGIN_ERR_PSW; //密码错误
            else
                msgType = MSG_SERVER_LOGIN_SUCCESS; //登陆成功
        }

        qDebug() << __FILE__<< __FUNCTION__ << "(): " << __LINE__ << "write back to client msgType = " << msgType;

        out << (quint16) 0 << msgType;
        out.device()->seek(0);
        out << (quint16)(block.size() - sizeof(quint16));
        tcpSocket->write(block);
        break;
    }
    default:
        break;
    }

    qDebug() << "db->closeDB()";
    db->closeDB();
    delete(db);
}

/*****************************************************************************
 * 创建一个QTcpSocket套接字，用构造是传入的socketDescriptor设置该套接字描述符，
 * 然后将其存入一个内置的未决连接列表(internal list of pending connections)
 * 最后，发送 newConnection()信号
 *****************************************************************************/

void QTcpThread::run()
{

    tcpSocket = new QTcpSocket;

    qDebug() << "QTcpThread run(), current thread is: " << QThread::currentThread();
    qDebug() << "Create new QTcpSocket, running in new thread";
    qDebug() << "Connect QTcpSocket's SIGNAL and LOTS, SIGNAL(readyRead()) and SLOTS(onReadyRead())";
    qDebug() << "Current thread is: " << QThread::currentThread();

    //关联信号-槽
    //QIODevice::readyRead() 。 函数的原型是 readyRead() 而不是 readReady() !!!!!，之前我把名字错误的写成了readReady().
    //readyRead, readyWrite
    //信号和槽函数需要加上圆括号'()'

    connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
    //connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(onReadyRead()), Qt::DirectConnection);

    if(!tcpSocket->setSocketDescriptor(socketDescriptor)){
        emit error(tcpSocket->error());
        return;
    }

    /*****************************************************************************
     * 进入事件处理循环(event loop)，定等待 exit() 被调用，返回传递给 exit() 的值。
     * 如果 exit() 是通过 quit() 调用的，则返回值为0。
     * 调用exec()函数以开始事件处理（event handling）是必要的。
     *****************************************************************************/
    //exec()函数是QThread的成员函数

    qDebug() << "QTcpThraed while loop exec....";

    exec();
}
